cmake_minimum_required(VERSION 3.17)
project(hpsocket)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR})


set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}")

find_package(PkgConfig QUIET)
pkg_search_module(SSL QUIET IMPORTED_TARGET openssl)
pkg_search_module(BROTLIDEC QUIET IMPORTED_TARGET libbrotlidec)
pkg_search_module(BROTLIENC QUIET IMPORTED_TARGET libbrotlienc)
pkg_search_module(BROTLICOMMON QUIET IMPORTED_TARGET libbrotlicommon)
pkg_search_module(ZLIB QUIET IMPORTED_TARGET zlib)
pkg_search_module(ICONV QUIET IMPORTED_TARGET iconv)

if (SSL_FOUND)
    message(${SSL_INCLUDEDIR} ", " ${SSL_LIBDIR} ", " ${SSL_LIBRARIES})
    include_directories(${SSL_INCLUDEDIR})
    link_directories(${SSL_LIBDIR})
    link_libraries(${SSL_LIBRARIES})
else ()
    find_package(OpenSSL)
endif ()

if (CRYPTO_FOUND)
    message(${CRYPTO_INCLUDEDIR})
    include_directories(${CRYPTO_INCLUDEDIR})
    link_directories(${CRYPTO_LIBDIR})
    link_libraries(${CRYPTO_LIBRARIES})
endif ()

if (BROTLIDEC_FOUND)
    message(${BROTLIDEC_INCLUDEDIR})
    include_directories(${BROTLIDEC_INCLUDEDIR})
    link_directories(${BROTLIDEC_LIBDIR})
    link_libraries(${BROTLIDEC_LIBRARIES})
endif ()

if (BROTLIENC_FOUND)
    message(${BROTLIENC_INCLUDEDIR})
    include_directories(${BROTLIENC_INCLUDEDIR})
    link_directories(${BROTLIENC_LIBDIR})
    link_libraries(${BROTLIENC_LIBRARIES})
endif ()

if (BROTLICOMMON_FOUND)
    message(${BROTLICOMMON_INCLUDEDIR})
    include_directories(${BROTLICOMMON_INCLUDEDIR})
    link_directories(${BROTLICOMMON_LIBDIR})
    link_libraries(${BROTLICOMMON_LIBRARIES})
endif ()

if (ZLIB_FOUND)
    message(${ZLIB_INCLUDEDIR})
    include_directories(${ZLIB_INCLUDEDIR})
    link_directories(${ZLIB_LIBDIR})
    link_libraries(${ZLIB_LIBRARIES})
else ()
    find_package(ZLIB)
endif ()

if (ICONV_FOUND)
    message(${ICONV_INCLUDEDIR})
    include_directories(${ICONV_INCLUDEDIR})
    link_directories(${ICONV_LIBDIR})
    link_libraries(${ICONV_LIBRARIES})
else ()
    find_package(iconv)
endif ()

add_definitions(-D_NEED_HTTP -D_SSL_SUPPORT -D_NEED_SSL -D_ICONV_SUPPORT)

aux_source_directory(src HPSOCKET_SOURCE_BASE_PATH)
aux_source_directory(4Cpp HPSOCKET_SOURCE_CPP_IMPL)
aux_source_directory(4C HPSOCKET_SOURCE_C_IMPL)
aux_source_directory(src/common HPSOCKET_SOURCE_COMMON_PATH)
aux_source_directory(src/common/crypto HPSOCKET_SOURCE_COMMON_CRYPTO_PATH)
aux_source_directory(src/common/http HPSOCKET_SOURCE_COMMON_HTTP_PATH)
aux_source_directory(src/common/kcp HPSOCKET_SOURCE_COMMON_KCP_PATH)

add_library(hpsocket SHARED
        ${HPSOCKET_SOURCE_CPP_IMPL}
        ${HPSOCKET_SOURCE_BASE_PATH}
        ${HPSOCKET_SOURCE_COMMON_PATH}
        ${HPSOCKET_SOURCE_COMMON_CRYPTO_PATH}
        ${HPSOCKET_SOURCE_COMMON_HTTP_PATH}
        ${HPSOCKET_SOURCE_COMMON_KCP_PATH})
target_include_directories(hpsocket PRIVATE include/hpsocket)
target_include_directories(hpsocket PRIVATE src)

add_library(hpsocket4c SHARED
        ${HPSOCKET_SOURCE_C_IMPL}
        ${HPSOCKET_SOURCE_BASE_PATH}
        ${HPSOCKET_SOURCE_COMMON_PATH}
        ${HPSOCKET_SOURCE_COMMON_CRYPTO_PATH}
        ${HPSOCKET_SOURCE_COMMON_HTTP_PATH}
        ${HPSOCKET_SOURCE_COMMON_KCP_PATH})
target_include_directories(hpsocket4c PRIVATE include/hpsocket)
target_include_directories(hpsocket4c PRIVATE src)

install(TARGETS hpsocket4c
        LIBRARY DESTINATION lib4c  # 动态库安装路径
        ARCHIVE DESTINATION lib4c  # 静态库安装路径
        RUNTIME DESTINATION bin4c  # 可执行文件安装路径
        PUBLIC_HEADER DESTINATION include/hpsocket  # 头文件安装路径
        )

set(TEST_HELPER_CPP test/helper.cpp)
set(TEST_HELPER_H test/helper.h)

set(ARQ_SERVER test/server/test5.cpp)
set(ARQ_CLIENT test/client/test6.cpp)

set(TCP_SERVER test/server/test1.cpp)
set(TCP_CLIENT test/client/test1.cpp)
set(TCP_AGENT test/client/test3.cpp)

set(TCP_SERVER_PACK test/server/test2.cpp)
set(TCP_CLIENT_PACK test/client/test2.cpp)
set(TCP_AGENT_PACK test/client/test4.cpp)

set(TCP_SERVER_PULL test/server/test7.cpp)
set(TCP_CLIENT_PULL test/client/test9.cpp)
set(TCP_AGENT_PULL test/client/testA.cpp)

set(UDP_CLIENT test/client/test5.cpp)
set(UDP_SEVER test/server/test3.cpp)
set(UDP_CAST test/client/test7.cpp)

set(HTTP_SERVER_4C test/server/test6.cpp)
set(HTTP_SERVER test/server/test4.cpp)
set(HTTP_CLIENT test/client/test8.cpp)

set(UDP_NODE test/client/testB.cpp)


add_definitions(-D_USE_HP_LIB)

add_executable(test_tcp_agent_pull
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_AGENT_PULL}
        )
target_link_libraries(test_tcp_agent_pull PRIVATE hpsocket)
target_include_directories(test_tcp_agent_pull PRIVATE include)
target_include_directories(test_tcp_agent_pull PRIVATE include/hpsocket)

add_executable(test_tcp_client_pull
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_CLIENT_PULL}
        )
target_link_libraries(test_tcp_client_pull hpsocket)
target_include_directories(test_tcp_client_pull PRIVATE include)
target_include_directories(test_tcp_client_pull PRIVATE include/hpsocket)

add_executable(test_tcp_server_pull
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_SERVER_PULL}
        )
target_link_libraries(test_tcp_server_pull hpsocket)
target_include_directories(test_tcp_server_pull PRIVATE include)
target_include_directories(test_tcp_server_pull PRIVATE include/hpsocket)

add_executable(test_http_client
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${HTTP_CLIENT}
        )
target_link_libraries(test_http_client hpsocket)
target_include_directories(test_http_client PRIVATE include)
target_include_directories(test_http_client PRIVATE include/hpsocket)

add_executable(test_http_server
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${HTTP_SERVER}
        )
target_link_libraries(test_http_server hpsocket)
target_include_directories(test_http_server PRIVATE include)
target_include_directories(test_http_server PRIVATE include/hpsocket)

add_executable(test_udp_cast
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${UDP_CAST}
        )
target_link_libraries(test_udp_cast hpsocket)
target_include_directories(test_udp_cast PRIVATE include)
target_include_directories(test_udp_cast PRIVATE include/hpsocket)

add_executable(test_udp_client
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${UDP_CLIENT}
        )
target_link_libraries(test_udp_client hpsocket)
target_include_directories(test_udp_client PRIVATE include)
target_include_directories(test_udp_client PRIVATE include/hpsocket)


add_executable(test_udp_server
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${UDP_SEVER}
        )
target_link_libraries(test_udp_server hpsocket)
target_include_directories(test_udp_server PRIVATE include)
target_include_directories(test_udp_server PRIVATE include/hpsocket)


add_executable(test_tcp_server_pack
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_SERVER_PACK}
        )
target_link_libraries(test_tcp_server_pack hpsocket)
target_include_directories(test_tcp_server_pack PRIVATE include)
target_include_directories(test_tcp_server_pack PRIVATE include/hpsocket)

add_executable(test_tcp_client_pack
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_CLIENT_PACK}
        )
target_link_libraries(test_tcp_client_pack hpsocket)
target_include_directories(test_tcp_client_pack PRIVATE include)
target_include_directories(test_tcp_client_pack PRIVATE include/hpsocket)

add_executable(test_tcp_agent_pack
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_AGENT_PACK}
        )
target_link_libraries(test_tcp_agent_pack hpsocket)
target_include_directories(test_tcp_agent_pack PRIVATE include)
target_include_directories(test_tcp_agent_pack PRIVATE include/hpsocket)

add_executable(test_tcp_server
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_SERVER}
        )
target_link_libraries(test_tcp_server hpsocket)
target_include_directories(test_tcp_server PRIVATE include)
target_include_directories(test_tcp_server PRIVATE include/hpsocket)

add_executable(test_tcp_client
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_CLIENT}
        )
target_link_libraries(test_tcp_client hpsocket)
target_include_directories(test_tcp_client PRIVATE include)
target_include_directories(test_tcp_client PRIVATE include/hpsocket)

add_executable(test_tcp_agent
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${TCP_AGENT}
        )
target_link_libraries(test_tcp_agent hpsocket)
target_include_directories(test_tcp_agent PRIVATE include)
target_include_directories(test_tcp_agent PRIVATE include/hpsocket)

add_executable(test_arq_server
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${ARQ_SERVER}
        )
target_link_libraries(test_arq_server hpsocket)
target_include_directories(test_arq_server PRIVATE include)
target_include_directories(test_arq_server PRIVATE include/hpsocket)

add_executable(test_arq_client
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${ARQ_CLIENT}
        )
target_link_libraries(test_arq_client hpsocket)
target_include_directories(test_arq_client PRIVATE include)
target_include_directories(test_arq_client PRIVATE include/hpsocket)

add_executable(test_server_4c
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${HTTP_SERVER_4C}
        )
target_link_libraries(test_server_4c hpsocket4c)
target_include_directories(test_server_4c PRIVATE include)
target_include_directories(test_server_4c PRIVATE include/hpsocket)

add_executable(test_udp_node
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${UDP_NODE}
        )
target_link_libraries(test_udp_node hpsocket)
target_include_directories(test_udp_node PRIVATE include)
target_include_directories(test_udp_node PRIVATE include/hpsocket)

set(HTTP_STREAM_MJPEG test/httpServer/HttpStreamMJPEG.cpp
        test/httpServer/MJPGSender.cpp
        test/httpServer/MJPGSender.h)
aux_source_directory(test/httpServer/Http/ HTTP_SERVER_WRAP_HTTP_DIR)
aux_source_directory(test/httpServer/Http/rax/ HTTP_SERVER_WRAP_HTTP_RAX_DIR)

find_package(OpenCV REQUIRED)
add_executable(test_http_stream_mjpeg
        ${TEST_HELPER_CPP}
        ${TEST_HELPER_H}
        ${HTTP_STREAM_MJPEG}
        ${HTTP_SERVER_WRAP_HTTP_DIR}
        ${HTTP_SERVER_WRAP_HTTP_RAX_DIR}
        )
target_link_libraries(test_http_stream_mjpeg PRIVATE hpsocket )
target_link_libraries(test_http_stream_mjpeg PRIVATE ${OpenCV_LIBS})

target_include_directories(test_http_stream_mjpeg PRIVATE include)
target_include_directories(test_http_stream_mjpeg PRIVATE include/hpsocket)
